unit SUContext;

interface
  uses
    System.Generics.Collections;

  const
    CONST_CONTEXT_DATA_DELAY = 500;
    CONST_CONTEXT_CLILOC_MINVALUE = 50000;
    CONST_CONTEXT_CLILOC_OFFSET = 300000;
  Type
    PContextEntry = class
      private
        m_Owner   : Cardinal;
        m_Index   : Byte;
        m_EntryID : Byte;
        m_Cliloc  : Cardinal;
        m_Flags   : Word;
        m_Color   : Word;
        m_Valid   : Boolean;
      public
        constructor Create(AOwner:Cardinal;Index:Byte;Data:String);

        function Click():Boolean;

        property EntryID : Byte           read m_EntryID;
        property Cliloc  : Cardinal       read m_Cliloc;
        property Flag    : Word           read m_Flags;
        property Color   : Word           read m_Color;
        property Valid   : Boolean        read m_Valid;
    end;

    PContextMenu = class
      private
        m_Owner : Cardinal;
        m_Entries: TList<PContextEntry>;

      public
        constructor Create(AOwner:Cardinal);
        function    Click(ClilocID:Cardinal):Boolean;
        procedure   Update();

        property Entries: TList<PContextEntry> read m_Entries;
    end;

implementation
  uses
    SUStealth,Classes,SysUtils;

{ PContextMenu }

function PContextMenu.Click(ClilocID: Cardinal): Boolean;
var
  Entry : PContextEntry;
begin
  Result := False;
  if(Assigned(m_Entries))then
  begin
    for Entry in m_Entries do
    begin
      if(Entry.Cliloc = ClilocID)then
      begin
        Result := Entry.Click;
        exit;
      end;
    end;
  end;
end;

constructor PContextMenu.Create(AOwner: Cardinal);
begin
  m_Owner := AOwner;
  m_Entries := TList<PContextEntry>.Create;
end;

procedure PContextMenu.Update;
var
  Data : TArray<String>;
  s    : String;
  Index: Byte;
begin
  Script.ContextMenu.RequestContextMenu(m_Owner);
  Script.Wait(CONST_CONTEXT_DATA_DELAY);
  Data := Script.ContextMenu.GetContextMenu();
  if(not assigned(m_Entries))then m_Entries := TList<PContextEntry>.Create();
  if(m_Entries.Count > 0)then m_Entries.Clear;
  Index := 0;
  for s in Data do
  begin
    m_Entries.Add(PContextEntry.Create(m_Owner,Index,s));
    Inc(Index);
  end;
  Script.ContextMenu.SetContextMenuHook(0,0);
  Script.ContextMenu.RequestContextMenu(0);
end;

{ PContextEntry }

function PContextEntry.Click: Boolean;
begin
  Result := False;
  if(m_Valid)then
  begin
    Result := True;
    Script.ContextMenu.SetContextMenuHook(m_Owner,m_Index);
    Script.ContextMenu.RequestContextMenu(m_Owner);
    Script.Wait(CONST_CONTEXT_DATA_DELAY);
    Script.ContextMenu.SetContextMenuHook(0,0);
    Script.ContextMenu.RequestContextMenu(0);
  end;
end;

constructor PContextEntry.Create(AOwner: Cardinal; Index: Byte; Data: String);
var
  StringHelper : TStrings;
  value        : Cardinal;
begin
  m_Owner := AOwner;
  m_Index := Index;
  StringHelper := TStringList.Create;
  Stringhelper.Delimiter := '|';
  StringHelper.DelimitedText := Data;
  m_Valid := False;
  try
  if(StringHelper.Count = 5)then
  begin
    m_Valid := True;
    m_EntryID := StrToInt(StringHelper[0]);
    value := StrToInt(StringHelper[1]);
    if(value < CONST_CONTEXT_CLILOC_MINVALUE)then value := value + CONST_CONTEXT_CLILOC_OFFSET;
    m_Cliloc := value;
    m_Flags := StrToInt(StringHelper[3]);
    m_Color := StrToInt(StringHelper[4]);
  end;
  except
    m_Valid := False;
  end;
  FreeAndNil(StringHelper);
end;

end.
